import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_getx/res/dimens/dimens.dart';

import 'my_refresh_list.dart';
import 'refresh_indicator.dart';
import 'state_layout.dart';

/// 封装下拉刷新与加载更多
class DeerSliverList extends StatefulWidget {
  const DeerSliverList({
    Key? key,
    required this.itemBuilder,
    required this.itemCount,
    required this.onRefresh,
    this.slivers,
    this.loadMore,
    this.hasMore = false,
    this.stateType = StateType.empty,
    this.onTapStateLayout,
    this.controller,
    this.physics = const AlwaysScrollableScrollPhysics(),
    this.constraints,
  }) : super(key: key);

  final RefreshCallback onRefresh;
  final LoadMoreCallback? loadMore;
  final IndexedWidgetBuilder itemBuilder;
  final int itemCount;
  final bool hasMore;
  final StateType stateType;
  final ScrollPhysics? physics;

  final GestureTapCallback? onTapStateLayout;
  final ScrollController? controller;
  final List<Widget>? slivers;
  final BoxConstraints? constraints;

  @override
  _DeerSliverListState createState() => _DeerSliverListState();
}

typedef RefreshCallback = Future<void> Function();
typedef LoadMoreCallback = Future<void> Function();

class _DeerSliverListState extends State<DeerSliverList> {
  /// 是否正在加载数据
  bool _isLoading = false;

  @override
  Widget build(BuildContext context) {
    final Widget child = MyRefreshIndicator(
        onRefresh: widget.onRefresh,
        child: CustomScrollView(controller: widget.controller, physics: widget.physics, slivers: [
                ...widget.slivers??[],
                widget.itemCount == 0
                    ? SliverToBoxAdapter(
                        child: Container(
                          constraints: widget.constraints ?? BoxConstraints(minHeight: Dp.dp_370),
                          child: StateLayout(
                            type: widget.stateType,
                            onTap: widget.onTapStateLayout,
                          ),
                        ),
                    ):
                SliverList(
                  delegate: SliverChildBuilderDelegate((context, index) {
                    /// 不需要加载更多则不需要添加FootView
                    if (widget.loadMore == null) {
                      return widget.itemBuilder(context, index);
                    } else {
                      return index < widget.itemCount
                          ? widget.itemBuilder(context, index)
                          : MoreWidget(widget.hasMore);
                    }
                  },
                      childCount: widget.loadMore == null
                          ? widget.itemCount
                          : widget.itemCount + 1),
                ),
              ]));
    return NotificationListener<ScrollNotification>(
      onNotification: (ScrollNotification note) {
        /// 确保是垂直方向滚动，且滑动至底部
        if (note.metrics.pixels == note.metrics.maxScrollExtent &&
            note.metrics.axis == Axis.vertical) {
          _loadMore();
        }
        return true;
      },
      child: child,
    );
  }

  Future<void> _loadMore() async {
    if (widget.loadMore == null) {
      return;
    }
    if (_isLoading) {
      return;
    }
    if (!widget.hasMore) {
      return;
    }
    _isLoading = true;
    await widget.loadMore?.call();
    _isLoading = false;
  }
}
